import { Component, IVec2, Sprite, SpriteFrame, Vec3, _decorator, tween } from "cc";
import { EntityTypeEnum, ExpTypeEnum, IActor, StateTypeEnum, distanceSqu } from "../../Common";
import { Vector2 } from "../../Common/RVO/Common";
import { RVOMath } from "../../Common/RVO/Common";
import DataManager from "../../Runtime/DataManager";
import { ObjectPoolManager } from "../../Runtime/ObjectPoolManager";
const { ccclass, property } = _decorator;

@ccclass('ExpManager')
export class ExpManager extends Component {

    @property(Sprite)
    body: Sprite

    @property(SpriteFrame)
    exp_green: SpriteFrame
    @property(SpriteFrame)
    exp_blue: SpriteFrame
    @property(SpriteFrame)
    exp_purple: SpriteFrame
    @property(SpriteFrame)
    exp_orange: SpriteFrame
    @property(SpriteFrame)
    exp_red: SpriteFrame

    targetActor: IActor
    isDead: boolean
    move2targetTag: boolean
    id: number
    type: ExpTypeEnum
    init(type: ExpTypeEnum, id: number) {
        this.isDead = false
        this.move2targetTag = false
        this.type = type
        this.id = id
        if (this.type === ExpTypeEnum.exp_green) {
            this.body.spriteFrame = this.exp_green
        } else if (this.type === ExpTypeEnum.exp_blue) {
            this.body.spriteFrame = this.exp_blue
        } else if (this.type === ExpTypeEnum.exp_purple) {
            this.body.spriteFrame = this.exp_purple
        } else if (this.type === ExpTypeEnum.exp_orange) {
            this.body.spriteFrame = this.exp_orange
        } else if (this.type === ExpTypeEnum.exp_red) {
            this.body.spriteFrame = this.exp_red
        }

    }

    render(pos: IVec2, state: StateTypeEnum) {
        this.node.setPosition(pos.x, pos.y)
        if (state === StateTypeEnum.dead && !this.isDead) {
            const actors = DataManager.Ins.state.actors
            this.isDead = true
            let targetActor = actors[actors.length - 1]
            for (let i = 0; i < actors.length - 1; i++) {
                if (distanceSqu(targetActor.position, pos) > distanceSqu(actors[i].position, pos)) {
                    targetActor = actors[i]
                }
            }
            this.playAnim(targetActor, pos)
        }
    }

    update(dt: number) {
        if (this.move2targetTag) {
            if (distanceSqu(this.node.position, this.targetActor.position) < 10 ** 2) {
                DataManager.Ins.expBallMap.delete(this.id)
                ObjectPoolManager.Ins.poolFreeNode(EntityTypeEnum.exp, this.node)
            } else {
                const dirX = this.targetActor.position.x - this.node.position.x
                const dirY = this.targetActor.position.y - this.node.position.y
                const dir = RVOMath.normalize(new Vector2(dirX, dirY))
                const speed = 800
                this.node.setPosition(this.node.position.x + dir.x * dt * speed, this.node.position.y + dir.y * dt * speed)
            }
        }
    }

    playAnim(targetActor: IActor, pos: IVec2) {
        this.targetActor = targetActor
        const dirX = pos.x - targetActor.position.x
        const dirY = pos.y - targetActor.position.y
        const dir = RVOMath.normalize(new Vector2(dirX, dirY))

        tween(this.node)
            .by(0.2, { position: new Vec3(dir.x * 60, dir.y * 60) })
            .call(() => {
                this.move2targetTag = true
            })
            .start()
    }
}